﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.Specialized;
using System.Web;
using System.Runtime.Serialization.Json;
using System.IO;
using System.Web.UI;
using ExtraClub.Domain.Entity;
using System.Text.RegularExpressions;
using System.Web.Caching;
using ExtraClub.Domain.Framework;
using System.Web.Security;
using System.Security.Principal;
using LB.Generics;

namespace ExtraClub.Domain {
    public static class JsonExtension {
        public static string ToJSON(this object obj) {
            string json = string.Empty;
            DataContractJsonSerializer ser = new DataContractJsonSerializer(obj.GetType());
            using (MemoryStream ms = new MemoryStream()) {
                ser.WriteObject(ms, obj);
                json = Encoding.Default.GetString(ms.ToArray());
            }
            return json;
        }

        public static T FromJSON<T>(this string json) {
            using (MemoryStream ms = new MemoryStream(ASCIIEncoding.Default.GetBytes(json))) {
                DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(T));
                return (T)ser.ReadObject(ms);
            }
        }
    }
    public static class WebUtils {
        public static string EncodeTo64(this object obj) {
            byte[] toEncodeAsBytes = System.Text.ASCIIEncoding.ASCII.GetBytes(obj.ToString());
            string returnValue = System.Convert.ToBase64String(toEncodeAsBytes);
            return returnValue;
        }
        static public string DecodeFrom64(this object obj) {
            byte[] encodedDataAsBytes = System.Convert.FromBase64String(obj.ToString());
            string returnValue = System.Text.ASCIIEncoding.ASCII.GetString(encodedDataAsBytes);
            return returnValue;
        }
        public static void RedirectTo404() {
            HttpResponse Response = HttpContext.Current.Response;
            Response.StatusCode = 404;
            Response.AddHeader("Location", "error_404.htm");
            Response.Redirect("/errors/error_404.htm");
        }

        public static void RedirectTo500(string error) {
            HttpResponse Response = HttpContext.Current.Response;
            Response.StatusCode = 500;
            Response.AddHeader("Error", error);
            Response.Redirect("/errors/error_500.htm?" + error);
        }

        //public static string FormUIText(string key, string fromFile) {
        //    string ret = "";
        //    UITextFormCollection collection = UITextFormCollection.GetUIText(fromFile);
        //    if (collection.ContainsKey(key)) {
        //        ret = collection[key];
        //    }
        //    return ret;
        //}
        public static bool isEmail(this object email) {
            string strRegex = @"[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?";
            Regex rex = new Regex(strRegex, RegexOptions.IgnoreCase | RegexOptions.Compiled);
            return rex.IsMatch(email.ToString().Trim());
        }
        public static bool isValidName(this object obj) {
            string strRegex = @"^\w*$";
            Regex rex = new Regex(strRegex, RegexOptions.IgnoreCase | RegexOptions.Compiled);
            return rex.IsMatch(obj.ToString().Trim());
        }

        #region Routines
        public static void PutIntoCach(string key, string path, object value) {
            CacheDependency dp = new CacheDependency(path);
            HttpRuntime.Cache.Add(key, value, dp, Cache.NoAbsoluteExpiration, Cache.NoSlidingExpiration, CacheItemPriority.NotRemovable, null);
        }
        //public static void OnRemoved(String key, object value, CacheItemRemovedReason removedReason) {
        //    if (removedReason == CacheItemRemovedReason.DependencyChanged) {
        //        //PutIntoCach(key, GetSiteData());
        //    }
        //}

        /// <summary>
        /// UI Text
        /// </summary>
        public static string GetUIText(string format, string module, string key) {
            return GetUIText(string.Format("~/Modules/" + format, module), key);
        }
        public static string GetUIText(string modulePath, string key) {
            Dictionary<string, string> ui = null;
            string path = HttpContext.Current.Server.MapPath(modulePath + "/text.xml");
            if (File.Exists(path)) {
                string lang = SiteContext.Current.Language;
                string cacheKey = path + lang;
                ui = (Dictionary<string, string>)HttpRuntime.Cache[cacheKey];
                if (ui == null) {
                    ui = UIXmlManager.GetUITextCollection(path, SiteContext.Current.Language);
                    WebUtils.PutIntoCach(cacheKey, path, ui);
                }
            }
            if (ui.ContainsKey(key)) {
                return ui[key];
            }
            return "undefied";
        }

        /// <summary>
        /// UI Style
        /// </summary>
        public static string GetUIStyle(string format, string module, string key) {
            Dictionary<string, string> ui = null;
            string path = HttpContext.Current.Server.MapPath(string.Format("~/Modules/" + format, module) + "/style.xml");
            if (File.Exists(path)) {
                ui = (Dictionary<string, string>)HttpRuntime.Cache[path];
                if (ui == null) {
                    ui = UIXmlManager.GetUIStyleCollection(path);
                    WebUtils.PutIntoCach(path, path, ui);
                }
            }
            if (ui.ContainsKey(key)) {
                return ui[key];
            }
            return "undefied";
        }
        #endregion

        public static string GetMessage(string returnUrl, string key) {
            string messageTemplate = WebUtils.GetUIText(HttpContext.Current.Request.AppRelativeCurrentExecutionFilePath.Replace("/module.asmx", ""), key);
            return string.Format(" " + messageTemplate, returnUrl);
        }
        public static void CheckIfRequestAuthorized(string pageUrl, IPrincipal user) {
            if (!UrlAuthorizationModule.CheckUrlAccessForPrincipal(string.Format(Constants.WEB_MODULES_PATH, pageUrl), user, "POST,GET")) {
                string msg = "Not autherized request!";
                throw new Exception(msg);
            }
        }
        public static string SetCommandUrl(ECommand command) {
            return SetCommandUrl(command, 0, "");
        }
        public static string SetCommandUrl(ECommand command, string form) {
            return SetCommandUrl(command, 0, form);
        }

        public static string UrlBuilder(string q) {
            string ret = null;

            NameValueCollection qs = new NameValueCollection(HttpContext.Current.Request.QueryString);
            NameValueCollection query = HttpUtility.ParseQueryString(q);
            foreach (string key in query.Keys) {
                qs[key] = query[key];
            }
            if (qs[Constants.QUERY_FROM_COMMAND] == ECommand.None.ToString()) {
                qs.Remove(Constants.QUERY_FROM_COMMAND);
            }
            ret = HttpContext.Current.Request.AppRelativeCurrentExecutionFilePath.Remove(0, 2) + StringExt.ToQS(qs);
            return ret;
        }
        public static string SetCommandUrl(ECommand command, int id, string form) {
            string ret = null;
            NameValueCollection qs = new NameValueCollection(HttpContext.Current.Request.QueryString);
            if (id > 0) {
                qs["id"] = id.ToString();
            }
            qs["form"] = form;
            if (string.IsNullOrEmpty(form)) {
                qs.Remove("form");
            }
            if (command != ECommand.None) {
                qs[Constants.QUERY_FROM_COMMAND] = command.ToString();
            } else {
                qs.Remove(Constants.QUERY_FROM_COMMAND);
            }
            ret = HttpContext.Current.Request.AppRelativeCurrentExecutionFilePath.Remove(0, 2) + StringExt.ToQS(qs);

            return ret;
        }
    }
}

